package com.wzz.utils.kms;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class KMeans {

    //算法分析成绩数据
    public static  List<List<Point>> getV(int k,int maxIterations ,List<Point> dataPoints,List<Point> clusterCenters){
        List<List<Point>> rd = new ArrayList<>();
//        int k = 2; // 设置簇的数量 ArrayList<>();
        clusterCenters.add(new Point(14, 89));
        clusterCenters.add(new Point(18, 87));

        for (int i = 0; i < maxIterations; i++) {
            // 分配数据点到最近的簇
            assignDataPointsToClusters(dataPoints, clusterCenters);

            // 计算新的簇中心
            List<Point> newClusterCenters = calculateClusterCenters(dataPoints, k);

            // 如果簇中心不再改变，结束迭代
            if (clusterCenters.equals(newClusterCenters)) {
                break;
            }
            clusterCenters = newClusterCenters;
        }
        // 打印簇中心和簇中的数据点
        for (int i = 0; i < k; i++) {
            List<Point> points = new ArrayList<>();
//            System.out.println("Cluster " + i + " center: " + clusterCenters.get(i));
//            System.out.println("Cluster " + i + " points: ");
            for (Point point : dataPoints) {
                if (point.getCluster() == i) {
                    Point point1 = new Point(point.getX(),point.getY(),point.getCluster());
                    points.add(point1);
                    System.out.println(point);
                }
            }
            System.out.println();
            rd.add(points);
        }
        return rd;
    }

    // 获取数据集
    private static List<Point> generateData() {
        List<Point> dataPoints = new ArrayList<>();
        return dataPoints;
    }

    // 设置簇中心
    private static List<Point> initializeClusterCenters(List<Point> dataPoints, int k) {
        List<Point> clusterCenters = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < k; i++) {
            Point randomPoint = dataPoints.get(random.nextInt(dataPoints.size()));
            clusterCenters.add(new Point(randomPoint.getX(), randomPoint.getY()));
        }
        return clusterCenters;
    }

    // 将数据点分配到最近的簇
    private static void assignDataPointsToClusters(List<Point> dataPoints, List<Point> clusterCenters) {
        for (Point point : dataPoints) {
            double minDistance = Double.MAX_VALUE;
            int closestCluster = -1;
            for (int i = 0; i < clusterCenters.size(); i++) {
                double distance = point.distanceTo(clusterCenters.get(i));
                if (distance < minDistance) {
                    minDistance = distance;
                    closestCluster = i;
                }
            }
            point.setCluster(closestCluster);
        }
    }

    // 计算新的簇中心
    private static List<Point> calculateClusterCenters(List<Point> dataPoints, int k) {
        List<Point> newClusterCenters = new ArrayList<>();
        for (int i = 0; i < k; i++) {
            double sumX = 0;
            double sumY = 0;
            int clusterSize = 0;
            for (Point point : dataPoints) {
                if (point.getCluster() == i) {
                    sumX += point.getX();
                    sumY += point.getY();
                    clusterSize++;
                }
            }
            if (clusterSize > 0) {
                double centerX = sumX / clusterSize;
                double centerY = sumY / clusterSize;
                newClusterCenters.add(new Point(centerX, centerY));
            }
        }
        return newClusterCenters;
    }



    public static void main2(String[] args) {
        int k = 2; // 设置簇的数量
        int maxIterations = 10; // 最大迭代次数
        List<Point> dataPoints = generateData(); // 生成示例数据集

        // 随机初始化簇中心
        List<Point> clusterCenters = initializeClusterCenters(dataPoints, k);
        clusterCenters = new ArrayList<>();
        clusterCenters.add(new Point(14, 89));
        clusterCenters.add(new Point(18, 87));

        for (int i = 0; i < maxIterations; i++) {
            // 分配数据点到最近的簇
            assignDataPointsToClusters(dataPoints, clusterCenters);

            // 计算新的簇中心
            List<Point> newClusterCenters = calculateClusterCenters(dataPoints, k);

            // 如果簇中心不再改变，结束迭代
            if (clusterCenters.equals(newClusterCenters)) {
                break;
            }

            clusterCenters = newClusterCenters;
        }

        // 打印簇中心和簇中的数据点
        for (int i = 0; i < k; i++) {
            System.out.println("Cluster " + i + " center: " + clusterCenters.get(i));
            System.out.println("Cluster " + i + " points: ");
            for (Point point : dataPoints) {
                if (point.getCluster() == i) {
                    System.out.println(point);
                }
            }
            System.out.println();
        }
    }

    public static void main(String[] args) {
        List<Point> dataPoints = new ArrayList<>();
        dataPoints.add(new Point(1, 0.25));
        dataPoints.add(new Point(1, 0));
        dataPoints.add(new Point(1, 0.35));
        dataPoints.add(new Point(1, 0));
        dataPoints.add(new Point(1, 0.5));
        dataPoints.add(new Point(1, 0.7));
        dataPoints.add(new Point(1, 0));
        dataPoints.add(new Point(1, 1));

        List<Point> clusterCenters = new ArrayList<>();
        clusterCenters.add(new Point(1, 0));
        clusterCenters.add(new Point(1, 0.5));
        clusterCenters.add(new Point(1, 0.8));
//        clusterCenters.add(new Point(19, 20));

        List<List<Point>> v = KMeans.getV(3,10,dataPoints,clusterCenters);
        System.out.println("------------最终结果：");
        System.out.println(v);
    }
}

